﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Если Сервер Или ТолстыйКлиентОбычноеПриложение Или ВнешнееСоединение Тогда

#Область СлужебныйПрограммныйИнтерфейс

// Проверяет требуется ли обновление или настройка информационной базы
// перед началом использования.
//
// Параметры:
//  НастройкаПодчиненногоУзлаРИБ - Булево - (возвращаемое значение), устанавливается Истина,
//                                 если обновление требуется в связи с настройкой подчиненного узла РИБ.
//
// Возвращаемое значение:
//  Булево - возвращает Истина, если требуется обновление или настройка информационной базы.
//
Функция НеобходимоОбновление(НастройкаПодчиненногоУзлаРИБ = Ложь) Экспорт
	
	Если ОбщегоНазначения.РазделениеВключено() Тогда
		// Обновление в модели сервиса.
		Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
			Если ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда
				// Заполнение разделенных параметров работы расширений.
				Возврат Истина;
			КонецЕсли;
			
		ИначеЕсли ОбновлениеИнформационнойБазыСлужебный.НеобходимоОбновлениеНеразделенныхДанныхИнформационнойБазы() Тогда
			// Обновление неразделенных параметров работы программы.
			Возврат Истина;
		КонецЕсли;
	Иначе
		// Обновление в локальном режиме.
		Если ОбновлениеИнформационнойБазы.НеобходимоОбновлениеИнформационнойБазы() Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
		МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
		
		// При запуске созданного начального образа подчиненного узла РИБ
		// загрузка не требуется, а обновление нужно выполнить.
		Если МодульОбменДаннымиСервер.НастройкаПодчиненногоУзлаРИБ() Тогда
			НастройкаПодчиненногоУзлаРИБ = Истина;
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

// Вызывает принудительное заполнение всех параметров работы программы.
Процедура ОбновитьВсеПараметрыРаботыПрограммы() Экспорт
	
	ЗагрузитьОбновитьПараметрыРаботыПрограммы();
	
КонецПроцедуры

// Возвращает дату успешной проверки/обновления параметров работы программы.
//
// Возвращаемое значение:
//  Дата
//
Функция ДатаОбновленияВсехПараметровРаботыПрограммы() Экспорт
	
	ИмяПараметра = "СтандартныеПодсистемы.БазоваяФункциональность.ДатаОбновленияВсехПараметровРаботыПрограммы";
	ДатаОбновления = СтандартныеПодсистемыСервер.ПараметрРаботыПрограммы(ИмяПараметра);
	
	Если ТипЗнч(ДатаОбновления) <> Тип("Дата") Тогда
		ДатаОбновления = '00010101';
	КонецЕсли;
	
	Возврат ДатаОбновления;
	
КонецФункции


// См. СтандартныеПодсистемыСервер.ПараметрРаботыПрограммы.
Функция ПараметрРаботыПрограммы(ИмяПараметра) Экспорт
	
	ОписаниеЗначения = ОписаниеЗначенияПараметраРаботыПрограммы(ИмяПараметра);
	
	Если СтандартныеПодсистемыСервер.ВерсияПрограммыОбновленаДинамически() Тогда
		Возврат ОписаниеЗначения.Значение;
	КонецЕсли;
	
	Если ОписаниеЗначения.Версия <> Метаданные.Версия Тогда
		Значение = Неопределено;
		ПроверитьВозможностьОбновленияВМоделиСервиса(ИмяПараметра, Значение, "Получение");
		Возврат Значение;
	КонецЕсли;
	
	Возврат ОписаниеЗначения.Значение;
	
КонецФункции

// См. СтандартныеПодсистемыСервер.УстановитьПараметрРаботыПрограммы.
Процедура УстановитьПараметрРаботыПрограммы(ИмяПараметра, Значение) Экспорт
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	ПроверитьВозможностьОбновленияВМоделиСервиса(ИмяПараметра, Значение, "Установка");
	
	ОписаниеЗначения = Новый Структура;
	ОписаниеЗначения.Вставить("Версия", Метаданные.Версия);
	ОписаниеЗначения.Вставить("Значение", Значение);
	
	УстановитьХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметра, ОписаниеЗначения);
	
КонецПроцедуры

// См. СтандартныеПодсистемыСервер.ОбновитьПараметрРаботыПрограммы.
Процедура ОбновитьПараметрРаботыПрограммы(ИмяПараметра, Значение, ЕстьИзменения = Ложь, СтароеЗначение = Неопределено) Экспорт
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	
	ОписаниеЗначения = ОписаниеЗначенияПараметраРаботыПрограммы(ИмяПараметра, Ложь);
	СтароеЗначение = ОписаниеЗначения.Значение;
	
	Если Не ОбщегоНазначения.ДанныеСовпадают(Значение, СтароеЗначение) Тогда
		ЕстьИзменения = Истина;
	ИначеЕсли ОписаниеЗначения.Версия = Метаданные.Версия Тогда
		Возврат;
	КонецЕсли;
	
	УстановитьПараметрРаботыПрограммы(ИмяПараметра, Значение);
	
КонецПроцедуры


// См. СтандартныеПодсистемыСервер.ИзмененияПараметраРаботыПрограммы.
Функция ИзмененияПараметраРаботыПрограммы(ИмяПараметра) Экспорт
	
	Если ОбщегоНазначения.РазделениеВключено()
	   И Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		
		// План обновления областей строится только для областей,
		// которые имеют версию не ниже версии неразделенных данных.
		// Для остальных областей запускаются все обработчики обновления.
		
		// Версия неразделенных (общих) данных.
		ВерсияИБ = ОбновлениеИнформационнойБазыСлужебный.ВерсияИБ(Метаданные.Имя, Истина);
	Иначе
		ВерсияИБ = ОбновлениеИнформационнойБазыСлужебный.ВерсияИБ(Метаданные.Имя);
	КонецЕсли;
	
	// При начальном заполнении изменение параметров работы программы не определено.
	Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИБ, "0.0.0.0") = 0 Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	ИмяПараметраХраненияИзменений = ИмяПараметра + УточнениеИмениПараметраХраненияИзменений();
	ПоследниеИзменения = ПараметрРаботыПрограммы(ИмяПараметраХраненияИзменений);
	
	Если Не ЭтоИзмененияПараметраРаботыПрограммы(ПоследниеИзменения) Тогда
		ПроверитьВозможностьОбновленияВМоделиСервиса(ИмяПараметра, Неопределено, "ПолучениеИзменений");
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Для параметра работы программы ""%1"" не найдены изменения.'"), ИмяПараметра)
			+ СтандартныеПодсистемыСервер.УточнениеОшибкиПараметровРаботыПрограммыДляРазработчика();
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Версия = Метаданные.Версия;
	СледующаяВерсия = СледующаяВерсия(Версия);
	ОбновлениеВнеОбновленияИБ = ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИБ, Версия) = 0;
	
	// Изменения к более старшим версиям не нужны,
	// кроме случая когда обновление выполняется вне обновления ИБ,
	// т.е. версия ИБ равна версии конфигурации.
	// В этом случае дополнительно выбираются изменения к следующей версии.
	
	Индекс = ПоследниеИзменения.Количество()-1;
	Пока Индекс >= 0 Цикл
		ВерсияИзменения = ПоследниеИзменения[Индекс].ВерсияКонфигурации;
		
		Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИБ, ВерсияИзменения) >= 0
		   И НЕ (  ОбновлениеВнеОбновленияИБ
		         И ОбщегоНазначенияКлиентСервер.СравнитьВерсии(СледующаяВерсия, ВерсияИзменения) = 0) Тогда
			
			ПоследниеИзменения.Удалить(Индекс);
		КонецЕсли;
		Индекс = Индекс - 1;
	КонецЦикла;
	
	Возврат ПоследниеИзменения.ВыгрузитьКолонку("Изменения");
	
КонецФункции

// См. СтандартныеПодсистемыСервер.ДобавитьИзмененияПараметраРаботыПрограммы.
Процедура ДобавитьИзмененияПараметраРаботыПрограммы(ИмяПараметра, Знач Изменения) Экспорт
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	
	// Получение версии ИБ или неразделенных данных.
	ВерсияИБ = ОбновлениеИнформационнойБазыСлужебный.ВерсияИБ(Метаданные.Имя);
	
	// При переходе на другую программу используется текущая версия конфигурации.
	Если Не ОбщегоНазначения.РазделениеВключено()
	   И ОбновлениеИнформационнойБазыСлужебный.РежимОбновленияДанных() = "ПереходСДругойПрограммы" Тогда
		
		ВерсияИБ = Метаданные.Версия;
	КонецЕсли;
	
	// При начальном заполнении добавление изменений параметров пропускается.
	Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИБ, "0.0.0.0") = 0 Тогда
		Изменения = Неопределено;
	КонецЕсли;
	
	ИмяПараметраХраненияИзменений = ИмяПараметра + УточнениеИмениПараметраХраненияИзменений();
	
	Блокировка = Новый БлокировкаДанных;
	ЭлементБлокировки = Блокировка.Добавить("РегистрСведений.ПараметрыРаботыПрограммы");
	ЭлементБлокировки.УстановитьЗначение("ИмяПараметра", ИмяПараметраХраненияИзменений);
	
	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		
		ОписаниеЗначения = ОписаниеЗначенияПараметраРаботыПрограммы(ИмяПараметраХраненияИзменений, Ложь);
		ПоследниеИзменения = ОписаниеЗначения.Значение;
		ОбновитьСоставИзменений = ОписаниеЗначения.Версия <> Метаданные.Версия;
		
		Если Не ЭтоИзмененияПараметраРаботыПрограммы(ПоследниеИзменения) Тогда
			ПоследниеИзменения = ХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметраХраненияИзменений);
			Если ЭтоИзмененияПараметраРаботыПрограммы(ПоследниеИзменения) Тогда
				ОбновитьСоставИзменений = Истина;
			Иначе
				ПоследниеИзменения = Неопределено;
			КонецЕсли;
		КонецЕсли;
		
		Если ПоследниеИзменения = Неопределено Тогда
			ОбновитьСоставИзменений = Истина;
			ПоследниеИзменения = КоллекцияИзмененийПараметраРаботыПрограммы();
		КонецЕсли;
		
		Если ЗначениеЗаполнено(Изменения) Тогда
			
			// Если производится обновление вне обновления ИБ,
			// тогда требуется добавить изменения к следующей версии,
			// чтобы при переходе на очередную версию, изменения
			// выполненные вне обновления ИБ были учтены.
			Версия = Метаданные.Версия;
			
			ОбновлениеВнеОбновленияИБ =
				ОбщегоНазначенияКлиентСервер.СравнитьВерсии(ВерсияИБ , Версия) = 0;
			
			Если ОбновлениеВнеОбновленияИБ Тогда
				Версия = СледующаяВерсия(Версия);
			КонецЕсли;
			
			ОбновитьСоставИзменений = Истина;
			Строка = ПоследниеИзменения.Добавить();
			Строка.Изменения          = Изменения;
			Строка.ВерсияКонфигурации = Версия;
		КонецЕсли;
		
		МинимальнаяВерсияИБ = ОбновлениеИнформационнойБазыСлужебныйПовтИсп.МинимальнаяВерсияИБ();
		
		// Удаление изменений для версий ИБ, которые меньше минимальной
		// вместо версий меньше или равных минимальной, чтобы обеспечить
		// возможность обновления вне обновления ИБ.
		Индекс = ПоследниеИзменения.Количество()-1;
		Пока Индекс >=0 Цикл
			ВерсияИзменения = ПоследниеИзменения[Индекс].ВерсияКонфигурации;
			
			Если ОбщегоНазначенияКлиентСервер.СравнитьВерсии(МинимальнаяВерсияИБ, ВерсияИзменения) > 0 Тогда
				ПоследниеИзменения.Удалить(Индекс);
				ОбновитьСоставИзменений = Истина;
			КонецЕсли;
			Индекс = Индекс - 1;
		КонецЦикла;
		
		Если ОбновитьСоставИзменений Тогда
			ПроверитьВозможностьОбновленияВМоделиСервиса(ИмяПараметра, Изменения, "ДобавлениеИзменений");
			УстановитьПараметрРаботыПрограммы(ИмяПараметраХраненияИзменений, ПоследниеИзменения);
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры


// Для вызова из процедуры ВыполнитьОбновлениеИнформационнойБазы.
Процедура ЗагрузитьОбновитьПараметрыРаботыПрограммы() Экспорт
	
	Если ОбщегоНазначения.РазделениеВключено()
	   И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		
		ОбновитьПараметрыРаботыВерсийРасширенийСУчетомРежимаВыполнения(Ложь);
		Возврат;
	КонецЕсли;
	
	Попытка
		Если ТребуетсяЗагрузитьПараметрыРаботыПрограммы() Тогда
			ЗагрузитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(Ложь);
		КонецЕсли;
	Исключение
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными")
		   И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
			МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
		ВызватьИсключение;
	КонецПопытки;
	
	Если ЗначениеЗаполнено(ПараметрыСеанса.ПодключенныеРасширения)
		И Не ВыполнятьОбновлениеБезФоновогоЗадания() Тогда
		// Запуск фонового задания обновления параметров.
		Результат = ОбновитьПараметрыРаботыПрограммыВФоне(Неопределено, Неопределено, Ложь);
		ОбработанныйРезультат = ОбработанныйРезультатДлительнойОперации(Результат, Ложь);
		
		Если ЗначениеЗаполнено(ОбработанныйРезультат.КраткоеПредставлениеОшибки) Тогда
			ВызватьИсключение ОбработанныйРезультат.ПодробноеПредставлениеОшибки;
		КонецЕсли;
	Иначе
		Попытка
			ОбновитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(Ложь);
		Исключение
			Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными")
			   И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
				МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
				МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
			КонецЕсли;
			ВызватьИсключение;
		КонецПопытки;
	КонецЕсли;
	
	ОбновитьПараметрыРаботыВерсийРасширенийСУчетомРежимаВыполнения(Ложь);
	
КонецПроцедуры

// Для процедуры ЗагрузитьОбновитьПараметрыРаботыПрограммы и вызова из формы ОбновлениеВерсииПрограммы.
//
// Возвращаемое значение:
//  Булево
//
Функция ТребуетсяЗагрузитьПараметрыРаботыПрограммы() Экспорт
	
	Возврат НеобходимоОбновление() И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ();
	
КонецФункции

// Для вызова из формы ОбновлениеВерсииПрограммы.
//
// Возвращаемое значение:
//   см. ДлительныеОперации.ВыполнитьВФоне
//
Функция ЗагрузитьПараметрыРаботыПрограммыВФоне(ОжидатьЗавершение, ИдентификаторФормы, СообщитьПрогресс) Экспорт
	
	ПараметрыОперации = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
	ПараметрыОперации.НаименованиеФоновогоЗадания = НСтр("ru = 'Фоновая загрузка параметров работы программы'");
	// Обновление должно выполняться в фоне для возможности видеть прогресс выполнения.
	// В режиме обновления запуск всех фоновых заданий прерывается специальной вставкой кода, поэтому
	// в файловом режиме заметных задержек запуска не будет даже при отсутствии монопольного режима.
	ПараметрыОперации.ЗапуститьВФоне = Истина;
	ПараметрыОперации.ОжидатьЗавершение = ОжидатьЗавершение;
	
	Если ОбщегоНазначения.РежимОтладки() Тогда
		СообщитьПрогресс = Ложь;
	КонецЕсли;
	
	Возврат ДлительныеОперации.ВыполнитьВФоне(
		"РегистрыСведений.ПараметрыРаботыПрограммы.ОбработчикДлительнойОперацииЗагрузкиПараметровРаботыПрограммы",
		СообщитьПрогресс,
		ПараметрыОперации);
	
КонецФункции

// Для вызова из формы ОбновлениеВерсииПрограммы.
// 
// Возвращаемое значение:
//   см. ДлительныеОперации.ВыполнитьВФоне
//
Функция ОбновитьПараметрыРаботыПрограммыВФоне(ОжидатьЗавершение, ИдентификаторФормы, СообщитьПрогресс) Экспорт
	
	ПараметрыОперации = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
	ПараметрыОперации.НаименованиеФоновогоЗадания = НСтр("ru = 'Фоновое обновление параметров работы программы'");
	ПараметрыОперации.БезРасширений = Истина;
	ПараметрыОперации.ОжидатьЗавершение = ОжидатьЗавершение;
	
	Если ОбщегоНазначения.РежимОтладки()
	   И Не ЗначениеЗаполнено(ПараметрыСеанса.ПодключенныеРасширения) Тогда
		СообщитьПрогресс = Ложь;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПараметрыСеанса.ПодключенныеРасширения)
	   И Не ДоступноВыполнениеФоновыхЗаданий() Тогда
		
		ТекстОшибки =
			НСтр("ru = 'Обновление параметров работы программы, когда подключены расширения конфигурации,
			           |может быть выполнено только в фоновом задании без расширений конфигурации.
			           |
			           |В файловой информационной базе фоновое задание невозможно запустить
			           |из другого фонового задания, а также из COM-Соединения.
			           |
			           |Для выполнения обновления необходимо, либо делать обновление интерактивно
			           |через запуск 1С:Предприятия, либо временно отключать расширения конфигурации.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Возврат ДлительныеОперации.ВыполнитьВФоне(
		"РегистрыСведений.ПараметрыРаботыПрограммы.ОбработчикДлительнойОперацииОбновленияПараметровРаботыПрограммы",
		СообщитьПрогресс, ПараметрыОперации);
	
КонецФункции

// Для вызова из формы ОбновлениеВерсииПрограммы.
//
// Возвращаемое значение:
//   см. ДлительныеОперации.ВыполнитьВФоне
//
Функция ОбновитьПараметрыРаботыВерсийРасширенийВФоне(ОжидатьЗавершение, ИдентификаторФормы, СообщитьПрогресс) Экспорт
	
	ПараметрыОперации = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
	ПараметрыОперации.НаименованиеФоновогоЗадания = НСтр("ru = 'Фоновое обновление параметров работы версий расширений'");
	// Обновление должно выполняться в фоне для возможности видеть прогресс выполнения.
	// В режиме обновления запуск всех фоновых заданий прерывается специальной вставкой кода, поэтому
	// в файловом режиме заметных задержек запуска не будет даже при отсутствии монопольного режима.
	ПараметрыОперации.ЗапуститьВФоне = Истина;
	ПараметрыОперации.ОжидатьЗавершение = ОжидатьЗавершение;
	
	Если ОбщегоНазначения.РежимОтладки()
	   И Не СтандартныеПодсистемыСервер.ЭтоРазделенныйРежимСеансаБезРазделителей() Тогда
		
		СообщитьПрогресс = Ложь;
	КонецЕсли;
	
	Возврат ДлительныеОперации.ВыполнитьВФоне(
		"РегистрыСведений.ПараметрыРаботыПрограммы.ОбработчикДлительнойОперацииОбновленияПараметровВерсийРасширений",
		СообщитьПрогресс,
		ПараметрыОперации);
	
КонецФункции

// Для вызова из формы ОбновлениеВерсииПрограммы.
//
// Возвращаемое значение:
//  Структура:
//    * КраткоеПредставлениеОшибки - Строка
//    * ПодробноеПредставлениеОшибки - Строка
//
Функция ОбработанныйРезультатДлительнойОперации(Результат, Операция) Экспорт
	
	КраткоеПредставлениеОшибки   = Неопределено;
	ПодробноеПредставлениеОшибки = Неопределено;
	
	Если Результат = Неопределено Или Результат.Статус = "Отменено" Тогда
		
		Если Операция = "ЗагрузкаПараметровРаботыПрограммы" Тогда
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось загрузить параметры работы программы по причине:
				           |Фоновое задание, выполняющее загрузку отменено.'");
			
		ИначеЕсли Операция = "ОбновлениеПараметровРаботыПрограммы" Тогда
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
				           |Фоновое задание, выполняющее обновление отменено.'");
			
		Иначе // ОбновлениеПараметровРаботыВерсийРасширений.
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось обновить параметры работы версий расширений по причине:
				           |Фоновое задание, выполняющее обновление отменено.'");
		КонецЕсли;
		
	ИначеЕсли Результат.Статус = "Выполнено" Тогда
		РезультатВыполнения = ПолучитьИзВременногоХранилища(Результат.АдресРезультата);
		УдалитьИзВременногоХранилища(Результат.АдресРезультата);
		
		Если ТипЗнч(РезультатВыполнения) = Тип("Структура") Тогда
			КраткоеПредставлениеОшибки   = РезультатВыполнения.КраткоеПредставлениеОшибки;
			ПодробноеПредставлениеОшибки = РезультатВыполнения.ПодробноеПредставлениеОшибки;
			
		ИначеЕсли Операция = "ЗагрузкаПараметровРаботыПрограммы" Тогда
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось загрузить параметры работы программы по причине:
				           |Фоновое задание, выполняющее загрузку не вернуло результат.'");
			
		ИначеЕсли Операция = "ОбновлениеПараметровРаботыПрограммы" Тогда
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
				           |Фоновое задание, выполняющее обновление не вернуло результат.'");
			
		Иначе // ОбновлениеПараметровРаботыВерсийРасширений.
			КраткоеПредставлениеОшибки =
				НСтр("ru = 'Не удалось обновить параметры работы версий расширений по причине:
				           |Фоновое задание, выполняющее обновление не вернуло результат.'");
		КонецЕсли;
		
	ИначеЕсли Результат.Статус <> "ЗагрузкаПараметровРаботыПрограммыНеТребуется"
	        И Результат.Статус <> "ЗагрузкаИОбновлениеПараметровРаботыПрограммыНеТребуются"
	        И Результат.Статус <> "ОбновлениеПараметровРаботыВерсийРасширенийНеТребуется" Тогда
		
		// Ошибка выполнения фонового задания.
		КраткоеПредставлениеОшибки   = Результат.КраткоеПредставлениеОшибки;
		ПодробноеПредставлениеОшибки = Результат.ПодробноеПредставлениеОшибки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(ПодробноеПредставлениеОшибки)
	   И    ЗначениеЗаполнено(КраткоеПредставлениеОшибки) Тогда
		
		ПодробноеПредставлениеОшибки = КраткоеПредставлениеОшибки;
	КонецЕсли;
	
	Если Не ЗначениеЗаполнено(КраткоеПредставлениеОшибки)
	   И    ЗначениеЗаполнено(ПодробноеПредставлениеОшибки) Тогда
		
		КраткоеПредставлениеОшибки = ПодробноеПредставлениеОшибки;
	КонецЕсли;
	
	ОбработанныйРезультат = Новый Структура;
	ОбработанныйРезультат.Вставить("КраткоеПредставлениеОшибки",   КраткоеПредставлениеОшибки);
	ОбработанныйРезультат.Вставить("ПодробноеПредставлениеОшибки", ПодробноеПредставлениеОшибки);
	
	Возврат ОбработанныйРезультат;
	
КонецФункции

#Область ИнструментРазработчикаОбновлениеВспомогательныхДанных

// Параметры:
//  Обновлять - Булево - начальное значение Ложь
//
// Возвращаемое значение:
//  Структура:
//   * БазоваяФункциональность - Структура:
//      ** ИдентификаторыОбъектовМетаданных  - см. СвойстваПараметраОбновления
//      ** ОчиститьКэшПрограммныхИнтерфейсов - см. СвойстваПараметраОбновления
//   * ПодключаемыеКоманды - Структура:
//      ** ПодключаемыеКомандыКонфигурации - см. СвойстваПараметраОбновления
//   * Пользователи - Структура:
//      ** ПроверитьНазначениеРолей - см. СвойстваПараметраОбновления
//   * УправлениеДоступом - Структура:
//      ** ПраваРолей                                    - см. СвойстваПараметраОбновления
//      ** ЗависимостиПрав                               - см. СвойстваПараметраОбновления
//      ** СвойстваВидовДоступа                          - см. СвойстваПараметраОбновления
//      ** ОписаниеПоставляемыхПрофилейГруппДоступа      - см. СвойстваПараметраОбновления
//      ** ОписаниеВозможныхПравДляНастройкиПравОбъектов - см. СвойстваПараметраОбновления
//   * ВариантыОтчетов - Структура:
//      ** ПараметрыОтчетовКонфигурации              - см. СвойстваПараметраОбновления
//      ** ПараметрыИндексаПоискаОтчетовКонфигурации - см. СвойстваПараметраОбновления
//   * ИнформацияПриЗапуске - Структура:
//      ** ПакетыИнформацииПриЗапуске - см. СвойстваПараметраОбновления
//   * КонтрольВеденияУчета - Структура:
//      ** СистемныеПроверкиУчета - см. СвойстваПараметраОбновления
//
Функция ПараметрыОбновления(Обновлять = Ложь) Экспорт
	
	Параметры = Новый Структура;
	
	// СтандартныеПодсистемы БазоваяФункциональность
	ПараметрыПодсистемы = Новый Структура;
	ПараметрыПодсистемы.Вставить("ИдентификаторыОбъектовМетаданных",  НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("ОчиститьКэшПрограммныхИнтерфейсов", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("БазоваяФункциональность", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы ПодключаемыеКоманды
	ПараметрыПодсистемы = Новый Структура;
	ПараметрыПодсистемы.Вставить("ПодключаемыеКомандыКонфигурации", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("ПодключаемыеКоманды", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы Пользователи
	ПараметрыПодсистемы = Новый Структура;
	ПараметрыПодсистемы.Вставить("ПроверитьНазначениеРолей", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("Пользователи", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы УправлениеДоступом
	ПараметрыПодсистемы.Вставить("ПраваРолей",                                    НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("ЗависимостиПрав",                               НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("СвойстваВидовДоступа",                          НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("ОписаниеПоставляемыхПрофилейГруппДоступа",      НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("ОписаниеВозможныхПравДляНастройкиПравОбъектов", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("УправлениеДоступом", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы ВариантыОтчетов
	ПараметрыПодсистемы.Вставить("ПараметрыОтчетовКонфигурации", НовыеСвойстваПараметраОбновления(Обновлять));
	ПараметрыПодсистемы.Вставить("ПараметрыИндексаПоискаОтчетовКонфигурации", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("ВариантыОтчетов", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы ИнформацияПриЗапуске
	ПараметрыПодсистемы.Вставить("ПакетыИнформацииПриЗапуске", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("ИнформацияПриЗапуске", ПараметрыПодсистемы);
	
	// СтандартныеПодсистемы КонтрольВеденияУчета
	ПараметрыПодсистемы.Вставить("СистемныеПроверкиУчета", НовыеСвойстваПараметраОбновления(Обновлять));
	Параметры.Вставить("КонтрольВеденияУчета", ПараметрыПодсистемы);
	
	Возврат Параметры;
	
КонецФункции

// Параметры:
//  Параметры - см. ПараметрыОбновления
//  ИдентификаторФормы - УникальныйИдентификатор
//
Процедура ВыполнитьОбновлениеНеразделенныхДанныхВФоне(Параметры, ИдентификаторФормы) Экспорт
	
	ПараметрыОперации = ДлительныеОперации.ПараметрыВыполненияВФоне(ИдентификаторФормы);
	ПараметрыОперации.НаименованиеФоновогоЗадания = НСтр("ru = 'Обновление неразделенных вспомогательных данных'");
	ПараметрыОперации.БезРасширений = Истина;
	ПараметрыОперации.ОжидатьЗавершение = Неопределено;
	
	ИмяПроцедуры = "РегистрыСведений.ПараметрыРаботыПрограммы.ОбработчикДлительнойОперацииВыполнитьОбновлениеНеразделенныхДанных";
	ДлительнаяОперация = ДлительныеОперации.ВыполнитьВФоне(ИмяПроцедуры, Параметры, ПараметрыОперации);
	
	Если ДлительнаяОперация.Статус <> "Выполнено" Тогда
		Если ДлительнаяОперация.Статус = "Ошибка" Тогда
			ТекстОшибки = ДлительнаяОперация.ПодробноеПредставлениеОшибки;
		ИначеЕсли ДлительнаяОперация.Статус = "Отменено" Тогда
			ТекстОшибки = НСтр("ru = 'Фоновое задание отменено'");
		Иначе
			ТекстОшибки = НСтр("ru = 'Ошибка выполнения фонового задания'");
		КонецЕсли;
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Результат = ПолучитьИзВременногоХранилища(ДлительнаяОперация.АдресРезультата);
	Если ТипЗнч(Результат) <> Тип("Структура") Тогда
		ТекстОшибки = НСтр("ru = 'Фоновое задание не вернуло результат'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Параметры = Результат;
	
КонецПроцедуры

// Параметры:
//  Параметры - см. ПараметрыОбновления
//  АдресРезультата - Строка
//
Процедура ОбработчикДлительнойОперацииВыполнитьОбновлениеНеразделенныхДанных(Параметры, АдресРезультата) Экспорт
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	
	Если ЗначениеЗаполнено(ПараметрыСеанса.ПодключенныеРасширения) Тогда
		ТекстОшибки =
			НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
			           |Найдены подключенные расширения конфигурации.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Если ОбщегоНазначения.РазделениеВключено()
	   И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстОшибки =
			НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
			           |Обновление невозможно выполнить в области данных.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	// СтандартныеПодсистемы БазоваяФункциональность
	Если Параметры.БазоваяФункциональность.ИдентификаторыОбъектовМетаданных.Обновлять Тогда
		Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(
			Параметры.БазоваяФункциональность.ИдентификаторыОбъектовМетаданных.ЕстьИзменения);
	КонецЕсли;
	Если Параметры.БазоваяФункциональность.ОчиститьКэшПрограммныхИнтерфейсов.Обновлять Тогда
		ОчиститьКэшПрограммныхИнтерфейсов(
			Параметры.БазоваяФункциональность.ОчиститьКэшПрограммныхИнтерфейсов.ЕстьИзменения);
	КонецЕсли;
	
	// СтандартныеПодсистемы ПодключаемыеКоманды
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ПодключаемыеКоманды") Тогда
		МодульПодключаемыеКоманды = ОбщегоНазначения.ОбщийМодуль("ПодключаемыеКоманды");
		Если Параметры.ПодключаемыеКоманды.ПодключаемыеКомандыКонфигурации.Обновлять Тогда
			Параметры.ПодключаемыеКоманды.ПодключаемыеКомандыКонфигурации.ЕстьИзменения =
				МодульПодключаемыеКоманды.ОперативноеОбновлениеОбщихДанныхКонфигурации().ЕстьИзменения;
		КонецЕсли;
	КонецЕсли;
	
	// СтандартныеПодсистемы Пользователи
	Если Параметры.Пользователи.ПроверитьНазначениеРолей.Обновлять Тогда
		Пользователи.ПроверитьНазначениеРолей(Истина);
	КонецЕсли;
	
	// СтандартныеПодсистемы УправлениеДоступом
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		Если Параметры.УправлениеДоступом.ПраваРолей.Обновлять Тогда
			МодульПраваРолей = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.ПраваРолей");
			МодульПраваРолей.ОбновитьДанныеРегистра(Параметры.УправлениеДоступом.ПраваРолей.ЕстьИзменения);
		КонецЕсли;
		Если Параметры.УправлениеДоступом.ЗависимостиПрав.Обновлять Тогда
			МодульЗависимостиПравДоступа = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.ЗависимостиПравДоступа");
			МодульЗависимостиПравДоступа.ОбновитьДанныеРегистра(Параметры.УправлениеДоступом.ЗависимостиПрав.ЕстьИзменения);
		КонецЕсли;
		Если Параметры.УправлениеДоступом.СвойстваВидовДоступа.Обновлять Тогда
			МодульУправлениеДоступомСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступомСлужебный");
			МодульУправлениеДоступомСлужебный.ОбновитьОписаниеСвойствВидовДоступа(
				Параметры.УправлениеДоступом.СвойстваВидовДоступа.ЕстьИзменения);
		КонецЕсли;
		Если Параметры.УправлениеДоступом.ОписаниеПоставляемыхПрофилейГруппДоступа.Обновлять Тогда
			МодульПрофилиГруппДоступа = ОбщегоНазначения.ОбщийМодуль("Справочники.ПрофилиГруппДоступа");
			МодульПрофилиГруппДоступа.ОбновитьСоставПредопределенныхПрофилей(
				Параметры.УправлениеДоступом.ОписаниеПоставляемыхПрофилейГруппДоступа.ЕстьИзменения);
			МодульПрофилиГруппДоступа.ОбновитьОписаниеПоставляемыхПрофилей(
				Параметры.УправлениеДоступом.ОписаниеПоставляемыхПрофилейГруппДоступа.ЕстьИзменения);
		КонецЕсли;
		Если Параметры.УправлениеДоступом.ОписаниеВозможныхПравДляНастройкиПравОбъектов.Обновлять Тогда
			МодульНастройкиПравОбъектов = ОбщегоНазначения.ОбщийМодуль("РегистрыСведений.НастройкиПравОбъектов");
			МодульНастройкиПравОбъектов.ОбновитьВозможныеПраваДляНастройкиПравОбъектов(
				Параметры.УправлениеДоступом.ОписаниеВозможныхПравДляНастройкиПравОбъектов.ЕстьИзменения);
		КонецЕсли;
	КонецЕсли;
	
	// СтандартныеПодсистемы ВариантыОтчетов
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ВариантыОтчетов") Тогда
		МодульВариантыОтчетов = ОбщегоНазначения.ОбщийМодуль("ВариантыОтчетов");
		Настройки = МодульВариантыОтчетов.ПараметрыОбновленияНастроек();
		Настройки.ОбщиеДанные = Истина; // Предопределенные.
		Настройки.РазделенныеДанные = Ложь;
		Если Параметры.ВариантыОтчетов.ПараметрыОтчетовКонфигурации.Обновлять Тогда
			Настройки.Конфигурация = Истина;
			Настройки.Расширения = Ложь;
			Настройки.Оперативное = Истина; // Обновление представлений и др.
			Настройки.Отложенное = Ложь;
			Параметры.ВариантыОтчетов.ПараметрыОтчетовКонфигурации.ЕстьИзменения =
				МодульВариантыОтчетов.Обновить(Настройки).ЕстьИзменения;
		КонецЕсли;
		Если Параметры.ВариантыОтчетов.ПараметрыИндексаПоискаОтчетовКонфигурации.Обновлять
		   И МодульВариантыОтчетов.РазрешеноИндексированиеНеразделенныхДанных() Тогда
			Настройки.Конфигурация = Истина;
			Настройки.Расширения = Ложь;
			Настройки.Оперативное = Ложь;
			Настройки.Отложенное = Истина; // Обновление индекса поиска по схеме СКД.
			Настройки.ИндексироватьСхему = Истина; // Принудительное перестроение индекса.
			Параметры.ВариантыОтчетов.ПараметрыИндексаПоискаОтчетовКонфигурации.ЕстьИзменения =
				МодульВариантыОтчетов.Обновить(Настройки).ЕстьИзменения;
		КонецЕсли;
	КонецЕсли;
	
	// СтандартныеПодсистемы ИнформацияПриЗапуске
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ИнформацияПриЗапуске") Тогда
		МодульИнформацияПриЗапуске = ОбщегоНазначения.ОбщийМодуль("ИнформацияПриЗапуске");
		Если Параметры.ИнформацияПриЗапуске.ПакетыИнформацииПриЗапуске.Обновлять Тогда
			Параметры.ИнформацияПриЗапуске.ПакетыИнформацииПриЗапуске.ЕстьИзменения =
				МодульИнформацияПриЗапуске.Обновить().ЕстьИзменения;
		КонецЕсли;
	КонецЕсли;
	
	// СтандартныеПодсистемы КонтрольВеденияУчета
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтрольВеденияУчета") Тогда
		МодульКонтрольВеденияУчетаСлужебный = ОбщегоНазначения.ОбщийМодуль("КонтрольВеденияУчетаСлужебный");
		Если Параметры.КонтрольВеденияУчета.СистемныеПроверкиУчета.Обновлять Тогда
			МодульКонтрольВеденияУчетаСлужебный.ОбновитьПараметрыПроверокУчета(
				Параметры.КонтрольВеденияУчета.СистемныеПроверкиУчета.ЕстьИзменения);
		КонецЕсли;
	КонецЕсли;
	
	ПоместитьВоВременноеХранилище(Параметры, АдресРезультата);
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

// Для вызова из фонового задания с текущим составом расширений конфигурации.
Процедура ОбработчикДлительнойОперацииЗагрузкиПараметровРаботыПрограммы(СообщитьПрогресс, АдресХранилища) Экспорт
	
	РезультатВыполнения = Новый Структура;
	РезультатВыполнения.Вставить("КраткоеПредставлениеОшибки",   Неопределено);
	РезультатВыполнения.Вставить("ПодробноеПредставлениеОшибки", Неопределено);
	
	Попытка
		ЗагрузитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(СообщитьПрогресс);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		РезультатВыполнения.КраткоеПредставлениеОшибки   = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
		РезультатВыполнения.ПодробноеПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		// Переход в режим открытия формы повторной синхронизации данных перед запуском
		// с двумя вариантами "Синхронизировать и продолжить" и "Продолжить".
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными")
		   И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
			МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
	КонецПопытки;
	
	ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресХранилища);
	
КонецПроцедуры

// Для вызова из фонового задания без подключенных расширений конфигурации.
Процедура ОбработчикДлительнойОперацииОбновленияПараметровРаботыПрограммы(СообщитьПрогресс, АдресХранилища) Экспорт
	
	РезультатВыполнения = Новый Структура;
	РезультатВыполнения.Вставить("КраткоеПредставлениеОшибки",   Неопределено);
	РезультатВыполнения.Вставить("ПодробноеПредставлениеОшибки", Неопределено);
	
	Попытка
		ОбновитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(СообщитьПрогресс);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		РезультатВыполнения.КраткоеПредставлениеОшибки   = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
		РезультатВыполнения.ПодробноеПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		// Переход в режим открытия формы повторной синхронизации данных перед запуском
		// с двумя вариантами "Синхронизировать и продолжить" и "Продолжить".
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными")
		   И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
			МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
	КонецПопытки;
	
	ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресХранилища);
	
КонецПроцедуры

// Для вызова из фонового задания с текущим составом расширений конфигурации.
Процедура ОбработчикДлительнойОперацииОбновленияПараметровВерсийРасширений(СообщитьПрогресс, АдресХранилища) Экспорт
	
	РезультатВыполнения = Новый Структура;
	РезультатВыполнения.Вставить("КраткоеПредставлениеОшибки",   Неопределено);
	РезультатВыполнения.Вставить("ПодробноеПредставлениеОшибки", Неопределено);
	
	Попытка
		ОбновитьПараметрыРаботыВерсийРасширенийСУчетомРежимаВыполнения(СообщитьПрогресс);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		РезультатВыполнения.КраткоеПредставлениеОшибки   = ОбработкаОшибок.КраткоеПредставлениеОшибки(ИнформацияОбОшибке);
		РезультатВыполнения.ПодробноеПредставлениеОшибки = ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке);
		// Переход в режим открытия формы повторной синхронизации данных перед запуском
		// с двумя вариантами "Синхронизировать и продолжить" и "Продолжить".
		Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными")
		   И ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
			МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
	КонецПопытки;
	
	ПоместитьВоВременноеХранилище(РезультатВыполнения, АдресХранилища);
	
КонецПроцедуры

Процедура ЗагрузитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(СообщитьПрогресс)
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	
	Если ОбщегоНазначения.РазделениеВключено()
	   И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстОшибки =
			НСтр("ru = 'Не удалось загрузить параметры работы программы по причине:
			           |Загрузку невозможно выполнить в области данных.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	НастройкаПодчиненногоУзлаРИБ = Ложь;
	Если Не НеобходимоОбновление(НастройкаПодчиненногоУзлаРИБ)
	 Или Не ОбщегоНазначения.ЭтоПодчиненныйУзелРИБ() Тогда
		Возврат;
	КонецЕсли;
	
	// РИБ-обмен данными, обновление в подчиненном узле ИБ.
	МодульОценкаПроизводительности = Неопределено;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности") Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
		МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если Не НастройкаПодчиненногоУзлаРИБ Тогда
		СтандартнаяОбработка = Истина;
		ОбщегоНазначенияПереопределяемый.ПередЗагрузкойПриоритетныхДанныхВПодчиненномРИБУзле(
			СтандартнаяОбработка);
		
		Если СтандартнаяОбработка = Истина
		   И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
			
			// Загрузка предопределенных элементов и идентификаторов объектов метаданных из главного узла.
			МодульОбменДаннымиСервер.ЗагрузитьПриоритетныеДанныеВПодчиненныйУзелРИБ();
		КонецЕсли;
		
	ИначеЕсли ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.РаботаВМоделиСервиса.ОбменДаннымиВМоделиСервиса") Тогда
		МодульАвтономнаяРаботаСлужебный = ОбщегоНазначения.ОбщийМодуль("АвтономнаяРаботаСлужебный");
		Если МодульАвтономнаяРаботаСлужебный.НеобходимоВыполнитьНастройкуАвтономногоРабочегоМестаПриПервомЗапуске() Тогда
			МодульАвтономнаяРаботаСлужебный.ВыполнитьНастройкуАвтономногоРабочегоМестаПриПервомЗапуске(Истина);
		КонецЕсли;
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(5);
	КонецЕсли;
	
	// Проверка загрузки идентификаторов объектов метаданных из главного узла.
	СписокКритичныхИзменений = "";
	Попытка
		Справочники.ИдентификаторыОбъектовМетаданных.ВыполнитьОбновлениеДанных(Ложь, Ложь, Истина, , СписокКритичныхИзменений);
	Исключение
		// Переход в режим открытия формы повторной синхронизации данных перед запуском
		// с одним вариантом "Синхронизировать и продолжить".
		Если Не НастройкаПодчиненногоУзлаРИБ
		   И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
		ВызватьИсключение;
	КонецПопытки;
	
	Если ЗначениеЗаполнено(СписокКритичныхИзменений) Тогда
		
		ИмяСобытия = НСтр("ru = 'Идентификаторы объектов метаданных.Требуется загрузить критичные изменения'",
			ОбщегоНазначения.КодОсновногоЯзыка());
		
		ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка, , , СписокКритичныхИзменений);
		
		// Переход в режим открытия формы повторной синхронизации данных перед запуском
		// с одним вариантом "Синхронизировать и продолжить".
		Если Не НастройкаПодчиненногоУзлаРИБ
		   И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
			МодульОбменДаннымиСервер.ВключитьПовторениеЗагрузкиСообщенияОбменаДаннымиПередЗапуском();
		КонецЕсли;
		
		ШаблонОшибки =
			НСтр("ru = 'Информационная база не может быть обновлена из-за проблемы в главном узле:
			           |- главный узел был некорректно обновлен (возможно не был увеличен номер версии конфигурации,
			           |  из-за чего не заполнился справочник Идентификаторы объектов метаданных);
			           |- либо были отменены к выгрузке приоритетные данные (элементы
			           |  справочника Идентификаторы объектов метаданных).
			           |
			           |Заново выполните обновление главного узла, зарегистрируйте к выгрузке
			           |приоритетные данные и повторите синхронизацию данных:
			           |- в главном узле запустите программу с параметром ""%1"";
			           |%2'");
		
		Если НастройкаПодчиненногоУзлаРИБ Тогда
			// Настройка подчиненного узла РИБ при первом запуске.
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОшибки,
				"/C" + " " + "ЗапуститьОбновлениеИнформационнойБазы",
				НСтр("ru = '- затем повторите создание подчиненного узла.'"));
		Иначе
			// Обновление подчиненного узла РИБ.
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ШаблонОшибки,
				"/C" + " " + "ЗапуститьОбновлениеИнформационнойБазы",
				НСтр("ru = '- затем повторите синхронизацию данных с этой информационной базой
				           | (сначала в главном узле, затем в этой информационной базе после перезапуска).'"));
		КонецЕсли;
		
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(10);
	КонецЕсли;
	
	Если МодульОценкаПроизводительности <> Неопределено Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ВремяЗагрузкиПриоритетныхДанных", ВремяНачала);
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбновитьПараметрыРаботыПрограммыСУчетомРежимаВыполнения(СообщитьПрогресс)
	
	СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
	
	Если ЗначениеЗаполнено(ПараметрыСеанса.ПодключенныеРасширения)
		И Не ВыполнятьОбновлениеБезФоновогоЗадания() Тогда
		ТекстОшибки =
			НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
			           |Найдены подключенные расширения конфигурации.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	Если ОбщегоНазначения.РазделениеВключено()
	   И ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		ТекстОшибки =
			НСтр("ru = 'Не удалось обновить параметры работы программы по причине:
			           |Обновление невозможно выполнить в области данных.'");
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;
	
	МодульОценкаПроизводительности = Неопределено;
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОценкаПроизводительности") Тогда
		МодульОценкаПроизводительности = ОбщегоНазначения.ОбщийМодуль("ОценкаПроизводительности");
		ВремяНачала = МодульОценкаПроизводительности.НачатьЗамерВремени();
	КонецЕсли;
	
	// Нет РИБ-обмена данными
	// или обновление в главном узле ИБ
	// или обновление при первом запуске подчиненного узла
	// или обновление после загрузки справочника "Идентификаторы объектов метаданных" из главного узла.
	ОбновитьПараметрыРаботыПрограммы(СообщитьПрогресс);
	
	Если МодульОценкаПроизводительности <> Неопределено Тогда
		МодульОценкаПроизводительности.ЗакончитьЗамерВремени("ВремяОбновленияКэшейМетаданных", ВремяНачала);
	КонецЕсли;
	
КонецПроцедуры

Процедура ОбновитьПараметрыРаботыВерсийРасширенийСУчетомРежимаВыполнения(СообщитьПрогресс)
	
	Если Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(65);
	КонецЕсли;
	
	Если ОбновлениеИнформационнойБазыСлужебный.УстановленоЗапуститьОбновлениеИнформационнойБазы() Тогда
		РегистрыСведений.ПараметрыРаботыВерсийРасширений.ОчиститьВсеПараметрыРаботыРасширений();
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(75);
	КонецЕсли;
	
	РегистрыСведений.ПараметрыРаботыВерсийРасширений.ЗаполнитьВсеПараметрыРаботыРасширений();
	РегистрыСведений.ПараметрыРаботыВерсийРасширений.ОтметитьЗаполнениеПараметровРаботыРасширений();
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(95);
	КонецЕсли;
	
КонецПроцедуры

// Для функции ИзмененияПараметраРаботыПрограммы.
Функция СледующаяВерсия(Версия)
	
	Массив = СтрРазделить(Версия, ".");
	
	Возврат ОбщегоНазначенияКлиентСервер.ВерсияКонфигурацииБезНомераСборки(
		Версия) + "." + Формат(Число(Массив[3]) + 1, "ЧГ=");
	
КонецФункции

// Для процедур ЗагрузитьОбновитьПараметрыРаботыПрограммы.
Процедура ОбновитьПараметрыРаботыПрограммы(СообщитьПрогресс = Ложь)
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(15);
	КонецЕсли;
	
	Если Не СтандартныеПодсистемыПовтИсп.ОтключитьИдентификаторыОбъектовМетаданных() Тогда
		Справочники.ИдентификаторыОбъектовМетаданных.ВыполнитьОбновлениеДанных(Ложь, Ложь, Ложь);
	КонецЕсли;
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(25);
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		МодульУправлениеДоступомСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступомСлужебный");
		МодульУправлениеДоступомСлужебный.ОбновитьПараметрыОграниченияДоступа();
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(45);
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтрольВеденияУчета") Тогда
		МодульКонтрольВеденияУчетаСлужебный = ОбщегоНазначения.ОбщийМодуль("КонтрольВеденияУчетаСлужебный");
		МодульКонтрольВеденияУчетаСлужебный.ОбновитьПараметрыПроверокУчета();
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(55);
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.ОбменДанными") Тогда
		МодульОбменДаннымиСервер = ОбщегоНазначения.ОбщийМодуль("ОбменДаннымиСервер");
		МодульОбменДаннымиСервер.ВыполнитьОбновлениеПравилДляОбменаДанными();
	КонецЕсли;
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.Печать") Тогда
		МодульУправлениеПечатью = ОбщегоНазначения.ОбщийМодуль("УправлениеПечатью");
		МодульУправлениеПечатью.ОбновитьКонтрольнуюСуммуМакетов();
	КонецЕсли;
	
	Если СообщитьПрогресс Тогда
		ДлительныеОперации.СообщитьПрогресс(65);
	КонецЕсли;
	
	ИмяПараметра = "СтандартныеПодсистемы.БазоваяФункциональность.ДатаОбновленияВсехПараметровРаботыПрограммы";
	СтандартныеПодсистемыСервер.УстановитьПараметрРаботыПрограммы(ИмяПараметра, ТекущаяДатаСеанса());
	
	Если ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных()
	   И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.УправлениеДоступом") Тогда
		
		МодульУправлениеДоступомСлужебный = ОбщегоНазначения.ОбщийМодуль("УправлениеДоступомСлужебный");
		МодульУправлениеДоступомСлужебный.УстановитьОбновлениеДоступа(Истина);
	КонецЕсли;
	
КонецПроцедуры

// Для функции ПараметрРаботыПрограммы и процедуры ОбновитьПараметрРаботыПрограммы.
Функция ОписаниеЗначенияПараметраРаботыПрограммы(ИмяПараметра, ПроверитьВозможностьОбновленияВМоделиСервиса = Истина)
	
	ОписаниеЗначения = ХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметра);
	
	Если ТипЗнч(ОписаниеЗначения) <> Тип("Структура")
	 Или ОписаниеЗначения.Количество() <> 2
	 Или Не ОписаниеЗначения.Свойство("Версия")
	 Или Не ОписаниеЗначения.Свойство("Значение") Тогда
		
		СтандартныеПодсистемыСервер.ПроверитьДинамическоеОбновлениеВерсииПрограммы();
		ОписаниеЗначения = Новый Структура("Версия, Значение");
		Если ПроверитьВозможностьОбновленияВМоделиСервиса Тогда
			ПроверитьВозможностьОбновленияВМоделиСервиса(ИмяПараметра, Null, "Получение");
		КонецЕсли;
	КонецЕсли;
	
	Возврат ОписаниеЗначения;
	
КонецФункции

// Для функции ОписаниеЗначенияПараметраРаботыПрограммы и
// процедур ДобавитьИзмененияПараметраРаботыПрограммы и
// и ПроверитьВозможностьОбновленияВМоделиСервиса.
//
Функция ХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметра)
	
	Запрос = Новый Запрос;
	Запрос.УстановитьПараметр("ИмяПараметра", ИмяПараметра);
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ПараметрыРаботыПрограммы.ХранилищеПараметра
	|ИЗ
	|	РегистрСведений.ПараметрыРаботыПрограммы КАК ПараметрыРаботыПрограммы
	|ГДЕ
	|	ПараметрыРаботыПрограммы.ИмяПараметра = &ИмяПараметра";
	
	Содержимое = Неопределено;
	
	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() Тогда
		Попытка
			Содержимое = Выборка.ХранилищеПараметра.Получить();
		Исключение
			// При внутренней ошибке извлечения данных, обработка выполняется также
			// как в случае, когда параметр еще не заполнен.
			Содержимое = Неопределено;
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'При получении параметра работы программы
				           |%1
				           |возникала ошибка извлечения значения из хранилища:
				           |%2'"),
				ИмяПараметра,
				ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
			ИмяСобытия = НСтр("ru = 'Параметры работы программы.Получение параметра'",
				ОбщегоНазначения.КодОсновногоЯзыка());
			ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Информация,,, Комментарий);
		КонецПопытки;
	КонецЕсли;
	УстановитьПривилегированныйРежим(Ложь);
	УстановитьОтключениеБезопасногоРежима(Ложь);
	
	Возврат Содержимое;
	
КонецФункции

// Для процедур УстановитьПараметрРаботыПрограммы.
Процедура УстановитьХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметра, ХранимыеДанные)
	
	НаборЗаписей = СлужебныйНаборЗаписей(РегистрыСведений.ПараметрыРаботыПрограммы);
	НаборЗаписей.Отбор.ИмяПараметра.Установить(ИмяПараметра);
	
	НоваяЗапись = НаборЗаписей.Добавить();
	НоваяЗапись.ИмяПараметра       = ИмяПараметра;
	НоваяЗапись.ХранилищеПараметра = Новый ХранилищеЗначения(ХранимыеДанные);
	
	НаборЗаписей.Записать();
	
КонецПроцедуры

Процедура ПроверитьВозможностьОбновленияВМоделиСервиса(Знач ИмяПараметра, НовоеЗначение, Знач Операция)
	
	Если Не ОбщегоНазначения.РазделениеВключено()
	 Или Не ОбщегоНазначения.ДоступноИспользованиеРазделенныхДанных() Тогда
		Возврат;
	КонецЕсли;
	
	Если СтрЗаканчиваетсяНа(ИмяПараметра, УточнениеИмениПараметраХраненияИзменений()) Тогда
		ИмяПараметра = Сред(ИмяПараметра, 1, СтрДлина(ИмяПараметра)
			- СтрДлина(УточнениеИмениПараметраХраненияИзменений()));
		Если Операция = "Получение" Тогда
			Операция = "ПолучениеИзменений";
		ИначеЕсли Операция = "Установка" Тогда
			Операция = "ДобавлениеИзменений";
		КонецЕсли;
	КонецЕсли;
	
	// Запись контекста ошибки в журнал регистрации для администратора сервиса.
	ОписаниеЗначения = ХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметра);
	
	ИмяПараметраХраненияИзменений = ИмяПараметра + УточнениеИмениПараметраХраненияИзменений();
	ПоследниеИзменения = ХранимыеДанныеПараметраРаботыПрограммы(ИмяПараметраХраненияИзменений);
	
	ИмяСобытия = НСтр("ru = 'Параметры работы программы.Не выполнено обновление в неразделенном режиме'",
		ОбщегоНазначения.КодОсновногоЯзыка());
	
	Комментарий = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
		НСтр("ru = '1. Перешлите сообщение в техническую поддержку.
		           |2. Попытайтесь устранить проблему самостоятельно. Для этого
		           |запустите программу с параметром командной строки 1С:Предприятия 8
		           |""%1"" от имени пользователя
		           |с правами администратора сервиса, то есть в неразделенном режиме.
		           |
		           |Сведения о проблемном параметре:'"),
		"/С" + " " + "ЗапуститьОбновлениеИнформационнойБазы");

	Комментарий = Комментарий + Символы.ПС +
	"ВерсияМетаданных = " + Метаданные.Версия + "
	|ИмяПараметра = " + ИмяПараметра + "
	|Операция = " + Операция + "
	|ОписаниеЗначения =
	|" + XMLСтрока(Новый ХранилищеЗначения(ОписаниеЗначения)) + "
	|НовоеЗначение =
	|" + XMLСтрока(Новый ХранилищеЗначения(НовоеЗначение)) + "
	|ПоследниеИзменения =
	|" + XMLСтрока(Новый ХранилищеЗначения(ПоследниеИзменения));
	
	ЗаписьЖурналаРегистрации(ИмяСобытия, УровеньЖурналаРегистрации.Ошибка,,, Комментарий);
	
	// Исключение для пользователя.
	ТекстОшибки =
		НСтр("ru = 'Параметры работы программы не обновлены в неразделенном режиме.
		           |Обратитесь к администратору сервиса. Подробности в журнале регистрации.'");
	
	ВызватьИсключение ТекстОшибки;
	
КонецПроцедуры

Функция УточнениеИмениПараметраХраненияИзменений()
	Возврат ":Изменения";
КонецФункции

// Параметры:
//  ПоследниеИзменения - см. КоллекцияИзмененийПараметраРаботыПрограммы
//
Функция ЭтоИзмененияПараметраРаботыПрограммы(ПоследниеИзменения)
	
	Если ТипЗнч(ПоследниеИзменения)              <> Тип("ТаблицаЗначений")
	 ИЛИ ПоследниеИзменения.Колонки.Количество() <> 2
	 ИЛИ ПоследниеИзменения.Колонки[0].Имя       <> "ВерсияКонфигурации"
	 ИЛИ ПоследниеИзменения.Колонки[1].Имя       <> "Изменения" Тогда
		
		Возврат Ложь;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция ДоступноВыполнениеФоновыхЗаданий()
	
	Если ТекущийРежимЗапуска() = Неопределено
	   И ОбщегоНазначения.ИнформационнаяБазаФайловая() Тогда
		
		Сеанс = ПолучитьТекущийСеансИнформационнойБазы();
		Если Сеанс.ИмяПриложения = "COMConnection"
		 Или Сеанс.ИмяПриложения = "BackgroundJob" Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;
	
	Возврат Истина;
	
КонецФункции

Функция ВыполнятьОбновлениеБезФоновогоЗадания()
	
	Если Не ДоступноВыполнениеФоновыхЗаданий() Тогда
		Возврат Истина;
	КонецЕсли;
	
	Возврат Ложь;
	
КонецФункции

// Возвращаемое значение:
//  ТаблицаЗначений:
//   * ВерсияКонфигурации - Строка
//   * Изменения - Произвольный
//
Функция КоллекцияИзмененийПараметраРаботыПрограммы()

	Результат = Новый ТаблицаЗначений;
	Результат.Колонки.Добавить("ВерсияКонфигурации");
	Результат.Колонки.Добавить("Изменения");

	Возврат Результат;
	
КонецФункции

// Создает набор записей служебного регистра, который не участвует в подписках на события.
// 
// Параметры:
//  МенеджерРегистра - РегистрСведенийМенеджер
//  
// Возвращаемое значение:
//  РегистрСведенийНаборЗаписей
//  
Функция СлужебныйНаборЗаписей(МенеджерРегистра) Экспорт
	
	НаборЗаписей = МенеджерРегистра.СоздатьНаборЗаписей();
	НаборЗаписей.ДополнительныеСвойства.Вставить("НеВыполнятьКонтрольУдаляемых");
	НаборЗаписей.ДополнительныеСвойства.Вставить("ОтключитьМеханизмРегистрацииОбъектов");
	НаборЗаписей.ОбменДанными.Получатели.АвтоЗаполнение = Ложь;
	НаборЗаписей.ОбменДанными.Загрузка = Истина;
	
	Возврат НаборЗаписей;
	
КонецФункции

#Область ИнструментРазработчикаОбновлениеВспомогательныхДанных

// Возвращаемое значение:
//  Структура:
//   * Обновлять     - Булево - начальное значение Истина.
//   * ЕстьИзменения - Булево - начальное значение Ложь.
//
Функция НовыеСвойстваПараметраОбновления(Обновлять)
	
	НовыеСвойства = Новый Структура;
	НовыеСвойства.Вставить("Обновлять", Обновлять);
	НовыеСвойства.Вставить("ЕстьИзменения", Ложь);
	
	Возврат НовыеСвойства;
	
КонецФункции

Процедура ОчиститьКэшПрограммныхИнтерфейсов(ЕстьИзменения)
	
	УстановитьПривилегированныйРежим(Истина);
	
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	ИСТИНА КАК ЗначениеИстина
	|ИЗ
	|	РегистрСведений.КэшПрограммныхИнтерфейсов КАК КэшПрограммныхИнтерфейсов";
	
	Блокировка = Новый БлокировкаДанных;
	Блокировка.Добавить("РегистрСведений.КэшПрограммныхИнтерфейсов");
	
	НачатьТранзакцию();
	Попытка
		Блокировка.Заблокировать();
		
		Если Не Запрос.Выполнить().Пустой() Тогда
			НаборЗаписей = РегистрыСведений.КэшПрограммныхИнтерфейсов.СоздатьНаборЗаписей();
			НаборЗаписей.Записать();
			ЕстьИзменения = Истина;
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

#КонецОбласти

#КонецОбласти

#КонецЕсли
